package com.ouyunc.gateway.config.oauth.override;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.ReactiveAuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.server.authorization.AuthorizationContext;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author fangzhenxun
 * @Description: 权限检查管理器，用于通过认证后，对持有该凭证的用户做权限的限制与验证
 * @Version V1.0
 **/
@Component
public class IReactiveAuthorizationManager implements ReactiveAuthorizationManager<AuthorizationContext>{
    private static Logger log = LoggerFactory.getLogger(IReactiveAuthorizationManager.class);



    /**
     * @Author fangzhenxun
     * @Description 在这里做权限的校验，放行与拦截，注意需要加上网关的匹配规则@todo 这里authentication为空
     * @param authentication
     * @param authorizationContext
     * @return reactor.core.publisher.Mono<org.springframework.security.authorization.AuthorizationDecision>
     */
    @Override
    public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, AuthorizationContext authorizationContext) {
        //从Redis中获取当前路径可访问角色列表
        ServerHttpRequest request = authorizationContext.getExchange().getRequest();
        String urlPath = request.getURI().getPath();
        List<String> authorities = new ArrayList<>();
        // 组装权限
        return Mono.just(new AuthorizationDecision(true));
//        return authentication
//                .filter(Authentication::isAuthenticated)
//                .flatMapIterable(Authentication::getAuthorities)
//                .map(GrantedAuthority::getAuthority)
//                .any(roleName -> {
//                    //roleName是当前用户的角色列表，可能呢会有多个，authorities数据库中匹配这个url的角色列表
//                    log.info("访问路径：{}", urlPath);
//                    log.info("用户角色roleName：{}", roleName);
//                    log.info("资源需要权限authorities：{}", authorities);
//                    return authorities.contains(roleName);
//                })
//                .map(AuthorizationDecision::new)
//                .defaultIfEmpty(new AuthorizationDecision(false));

    }
}
